home *** CD-ROM | disk | FTP | other *** search
/ Gekikoh Dennoh Club 5 / Gekikoh Dennoh Club Vol. 5 (Japan).7z / Gekikoh Dennoh Club Vol. 5 (Japan) (Track 01).bin / internet / xip / iijppp.lzh / src / os.c < prev    next >
C/C++ Source or Header  |  1994-10-13  |  7KB  |  330 lines

  1. /*
  2.  *          PPP OS Layer Interface Module
  3.  *
  4.  *        Written by Toshiharu OHNO (tony-o@iij.ad.jp)
  5.  *
  6.  *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
  7.  *
  8.  * Redistribution and use in source and binary forms are permitted
  9.  * provided that the above copyright notice and this paragraph are
  10.  * duplicated in all such forms and that any documentation,
  11.  * advertising materials, and other materials related to such
  12.  * distribution and use acknowledge that the software was developed
  13.  * by the Internet Initiative Japan, Inc.  The name of the
  14.  * IIJ may not be used to endorse or promote products derived
  15.  * from this software without specific prior written permission.
  16.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  17.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  18.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19.  *
  20.  */
  21. #include "fsm.h"
  22. #include <sys/param.h>
  23. #include <sys/socket.h>
  24. #include <net/route.h>
  25. #if defined(__NetBSD__) || _BSDI_VERSION >= 199312
  26. #include <sys/select.h>
  27. #endif
  28. #include <sys/ioctl.h>
  29. #include <fcntl.h>
  30. #include <net/if.h>
  31. #include <net/if_tun.h>
  32. #include <errno.h>
  33. #include "ipcp.h"
  34. #include "os.h"
  35.  
  36. static struct ifaliasreq ifra;
  37. static struct ifreq ifrq;
  38. static struct in_addr oldmine, oldhis;
  39. static int linkup;
  40.  
  41. #ifdef bsdi
  42. extern char *inet_ntoa();
  43. #endif
  44. extern void HangupModem();
  45.  
  46. char *IfDevName;
  47.  
  48. static int
  49. SetIpDevice(myaddr, hisaddr, netmask, updown)
  50. struct in_addr myaddr, hisaddr, netmask;
  51. int updown;
  52. {
  53.   struct sockaddr_in *sin;
  54.   int s;
  55.   int changeaddr = 0;
  56.   u_long mask, addr;
  57.  
  58.   s = socket(AF_INET, SOCK_DGRAM, 0);
  59.   if (s < 0) {
  60.     perror("socket");
  61.     return(-1);
  62.   }
  63.  
  64.   if (updown == 0) {
  65.     if (oldmine.s_addr == 0 && oldhis.s_addr == 0) {
  66.       return(0);
  67.     }
  68.     bzero(&ifra.ifra_addr, sizeof(ifra.ifra_addr));
  69.     bzero(&ifra.ifra_broadaddr, sizeof(ifra.ifra_addr));
  70.     bzero(&ifra.ifra_mask, sizeof(ifra.ifra_addr));
  71. #ifdef DEBUG
  72.     logprintf("DIFADDR\n");
  73. #endif
  74.     if (ioctl(s, SIOCDIFADDR, &ifra) < 0) {
  75.       perror("SIOCDIFADDR");
  76.       return(-1);
  77.     }
  78.  
  79.     oldmine.s_addr = oldhis.s_addr = 0;
  80.   } else {
  81.     /*
  82.      * If given addresses are alreay set, then ignore this request.
  83.      */
  84.     if (oldmine.s_addr == myaddr.s_addr && oldhis.s_addr == hisaddr.s_addr)
  85.       return(0);
  86.     /*
  87.      * If different address has been set, then delete it first.
  88.      */
  89.     if (oldmine.s_addr || oldhis.s_addr) {
  90.       changeaddr = 1;
  91.     }
  92.     /*
  93.      *  Set interface address
  94.      */
  95.     sin = (struct sockaddr_in *)&(ifra.ifra_addr);
  96.     sin->sin_family = AF_INET;
  97.     sin->sin_addr = oldmine = myaddr;
  98.     sin->sin_len = sizeof(*sin);
  99.     /*
  100.      *  Set destination address
  101.      */
  102.     sin = (struct sockaddr_in *)&(ifra.ifra_broadaddr);
  103.     sin->sin_family = AF_INET;
  104.     sin->sin_addr = oldhis = hisaddr;
  105.     sin->sin_len = sizeof(*sin);
  106.     /*
  107.      */
  108.     addr = ntohl(myaddr.s_addr);
  109.     if (IN_CLASSA(addr))
  110.       mask = IN_CLASSA_NET;
  111.     else if (IN_CLASSB(addr))
  112.       mask = IN_CLASSB_NET;
  113.     else
  114.       mask = IN_CLASSC_NET;
  115.     /*
  116.      *  if subnet mask is given, use it instead of class mask.
  117.      */
  118.     if (netmask.s_addr && (ntohl(netmask.s_addr) & mask) == mask)
  119.       mask = ntohl(netmask.s_addr);
  120.  
  121.     sin = (struct sockaddr_in *)&(ifra.ifra_mask);
  122.     sin->sin_family = AF_INET;
  123.     sin->sin_addr.s_addr = htonl(mask);
  124.     sin->sin_len = sizeof(*sin);
  125.  
  126.     if (changeaddr) {
  127.       /*
  128.        * Interface already exists. Just change the address.
  129.        */
  130.       bcopy(&ifra.ifra_addr, &ifrq.ifr_addr, sizeof(struct sockaddr));
  131.       if (ioctl(s, SIOCSIFADDR, &ifra) < 0)
  132.     perror("SIFADDR");;
  133.       bcopy(&ifra.ifra_broadaddr, &ifrq.ifr_dstaddr, sizeof(struct sockaddr));
  134.       if (ioctl(s, SIOCSIFDSTADDR, &ifrq) < 0)
  135.     perror("SIFDSTADDR");;
  136. #ifdef notdef
  137.       bcopy(&ifra.ifra_mask, &ifrq.ifr_broadaddr, sizeof(struct sockaddr));
  138.       if (ioctl(s, SIOCSIFBRDADDR, &ifrq) < 0)
  139.     perror("SIFBRDADDR");
  140. #endif
  141.     } else if (ioctl(s, SIOCAIFADDR, &ifra) < 0) {
  142.       perror("SIOCAIFADDR");
  143.       return(-1);
  144.     }
  145.   }
  146.   close(s);
  147.   return(0);
  148. }
  149.  
  150. int
  151. OsSetIpaddress(myaddr, hisaddr, netmask)
  152. struct in_addr myaddr, hisaddr, netmask;
  153. {
  154.   return(SetIpDevice(myaddr, hisaddr, netmask, 1));
  155. }
  156.  
  157. static struct in_addr peer_addr;
  158. struct in_addr defaddr;
  159.  
  160. void
  161. OsLinkup()
  162. {
  163.   char *s;
  164.  
  165.   if (linkup == 0) {
  166.     if (setuid(0) < 0)
  167.     logprintf("setuid failed\n");
  168.     peer_addr = IpcpInfo.his_ipaddr;
  169.     s = (char *)inet_ntoa(peer_addr);
  170.     LogPrintf(LOG_PHASE, "OsLinkup: %s\n", s);
  171.  
  172.     if (SelectSystem(inet_ntoa(IpcpInfo.want_ipaddr), LINKFILE) < 0) {
  173.       if (dstsystem) {
  174.         if (SelectSystem(dstsystem, LINKFILE) < 0)
  175.           SelectSystem("MYADDR", LINKFILE);
  176.       } else
  177.         SelectSystem("MYADDR", LINKFILE);
  178.     }
  179.     linkup = 1;
  180.   }
  181. }
  182.  
  183. void
  184. OsLinkdown()
  185. {
  186.   char *s;
  187.  
  188.   if (linkup) {
  189.     s = (char *)inet_ntoa(peer_addr);
  190.     LogPrintf(LOG_PHASE, "OsLinkdown: %s\n", s);
  191.     if (!(mode & MODE_AUTO))
  192.       DeleteIfRoutes(0);
  193.     linkup = 0;
  194.   }
  195. }
  196.  
  197. int
  198. OsInterfaceDown(final)
  199. int final;
  200. {
  201.   struct in_addr zeroaddr;
  202.   int s;
  203.  
  204.   OsLinkdown();
  205.   if (!final && (mode & MODE_AUTO))    /* We still want interface alive */
  206.     return(0);
  207.   s = socket(AF_INET, SOCK_DGRAM, 0);
  208.   if (s < 0) {
  209.     perror("socket");
  210.     return(-1);
  211.   }
  212.   ifrq.ifr_flags &= ~IFF_UP;
  213.   if (ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {
  214.     perror("SIOCSIFFLAGS");
  215.     close(s);
  216.     return(-1);
  217.   }
  218.  
  219.   zeroaddr.s_addr = 0;
  220.   SetIpDevice(zeroaddr, zeroaddr, zeroaddr, 0);
  221.  
  222.   close(s);
  223.   return(0);
  224. }
  225.  
  226. void
  227. OsSetInterfaceParams(type, mtu, speed)
  228. int type, mtu, speed;
  229. {
  230.   struct tuninfo info;
  231.  
  232.   info.if_type = type;
  233.   info.if_mtu = mtu;
  234.   info.if_baudrate = speed;
  235.   if (ioctl(tun_out, TUNSIFINFO, &info) < 0)
  236.     perror("TUNSIFINFO");
  237. }
  238.  
  239. /*
  240.  *  Open tunnel device and returns its descriptor
  241.  */
  242. int
  243. OpenTunnel(ptun)
  244. int *ptun;
  245. {
  246.   int s;
  247.   char *cp;
  248.   char *suffix = "0123456789";
  249.   char ifname[IFNAMSIZ];
  250.   char devname[12];
  251.  
  252.   strcpy(devname, "/dev/tun0");
  253.   for (cp = suffix; *cp; cp++) {
  254.     devname[8] = *cp;
  255.     tun_out = open(devname, O_RDWR);
  256.     if (tun_out >= 0)
  257.       break;
  258.   }
  259.   *ptun = cp - suffix;
  260.   if (*cp == '\0') {
  261.     fprintf(stderr, "No tunnel device is available.\n");
  262.     return(-1);
  263.   }
  264.  
  265.   /*
  266.    * At first, name the interface.
  267.    */
  268.   strcpy(ifname, devname + 5);
  269.  
  270.   bzero((char *)&ifra, sizeof(ifra));
  271.   bzero((char *)&ifrq, sizeof(ifrq));
  272.  
  273.   strncpy(ifrq.ifr_name, ifname, IFNAMSIZ);
  274.   strncpy(ifra.ifra_name, ifname, IFNAMSIZ);
  275.  
  276.   s = socket(AF_INET, SOCK_DGRAM, 0);
  277.   if (s < 0) {
  278.     perror("socket");
  279.     return(-1);
  280.   }
  281.  
  282.   /*
  283.    *  Now, bring up the interface.
  284.    */
  285.   if (ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) {
  286.     perror("SIOCGIFFLAGS");
  287.     close(s);
  288.     return(-1);
  289.   }
  290.  
  291.   ifrq.ifr_flags |= IFF_UP;
  292.   if (ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {
  293.     perror("SIOCSIFFLAGS");
  294.     close(s);
  295.     return(-1);
  296.   }
  297.  
  298.   tun_in = tun_out;
  299.   IfDevName = devname + 5;
  300.   if (GetIfIndex(IfDevName) < 0) {
  301.     fprintf(stderr, "can't find ifindex.\n");
  302.     close(s);
  303.     return(-1);
  304.   }
  305.   printf("Using interface: %s\r\n", IfDevName);
  306.   LogPrintf(LOG_PHASE, "Using interface: %s\n", IfDevName);
  307.   close(s);
  308.   return(0);
  309. }
  310.  
  311. void
  312. OsCloseLink(flag)
  313. int flag;
  314. {
  315.   HangupModem(flag);
  316. }
  317.  
  318. void
  319. OsAddInOctets(cnt)
  320. int cnt;
  321. {
  322. }
  323.  
  324. void
  325. OsAddOutOctets(cnt)
  326. int cnt;
  327. {
  328. }
  329.  
  330.